package gecko.dingtalk;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiUserGetRequest;
import com.dingtalk.api.response.OapiUserGetResponse;
import gecko.AbstractInterceptor;
import gecko.GeckoContext;
import gecko.GeckoScoped;
import gecko.lang.JSONObject;
import gecko.lang.TypedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 连接到钉钉服务器的拦截器：
 * 接收到校验信息时，使用用户ID向钉钉服务器检查用户是否有权限。
 *
 * @author 陈永佳 (yoojiachen@gmail.com)
 * @version 0.0.1
 */
public class DingTalkAuthInterceptor extends AbstractInterceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(DingTalkAuthInterceptor.class);

    private DingTalkClient mDingTalkClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/get");

    private String mRobotToken = "";

    @Override
    public void onInit(TypedMap initArgs, GeckoScoped scoped) {
        super.onInit(initArgs, scoped);
        mRobotToken = initArgs.getString(DingTalk.CONF_ACCESS_TOKEN);
    }

    @Override
    public void handle(GeckoContext context, GeckoScoped scoped) throws Exception {
        // 检查Context附带的参数：
        // 1. 指定 auth-type 为 dingtalk
        // 2. 带有 userid 参数
        final TypedMap attr = TypedMap.wrap(context.attributes());
        if (attr.fieldEqualTo("auth-type", "dingtalk") && attr.containsKey("userid")) {
            final OapiUserGetRequest request = new OapiUserGetRequest();
            final String userId = attr.getString("userid");
            request.setUserid(userId);
            request.setHttpMethod("GET");
            OapiUserGetResponse resp = mDingTalkClient.execute(request, mRobotToken);

            if (resp.isSuccess()) {
                LOGGER.warn("钉钉服务，用户校验成功： {}({}): {}", resp.getName(), resp.getUserid(), resp.getJobnumber());
                if (!resp.getActive()) {
                    context.outbound().addDataFields(JSONObject.error("用户" + resp.getName() + "未激活"));
                    drop("钉钉用户未激活");
                }
            } else {
                LOGGER.warn("钉钉服务，用户校验失败： {}", resp.getErrmsg());
                context.outbound().addDataFields(JSONObject.error(resp.getErrmsg()));
                drop("钉钉用户校验失败");
            }
        }
    }
}
